package com.ggj2013.hbh;

import com.ggj2013.hbh.utils.SoundPlayer;
import nme.display.MovieClip;
import nme.display.Bitmap;
import nme.geom.Point;
import com.ggj2013.hbh.utils.Tools;
import com.ggj2013.hbh.utils.CollisionDetection;

/**
 * @author Jonathan Moriarty
 */
class Level extends MovieClip {

	//private var _background:Bitmap;
	public var targetPoint:Point;
	public var rooms:Array<Room>;
	public static inline var levelDiameter:Int = 3000;
	public static inline var maxRoomCount:Int = 5;
	public static inline var roomBuffer:Int = Door.doorDepth;
	
	public function new( l_levelNum:Int = 0 ) {
		super();		
		makeRooms();
	}
	
	public function makeRooms():Void {
		rooms = new Array<Room>();
		var roomChance = Tools.randomInt(4, 0);
		var firstRoom:Room = new Room("room01", "room01");
		switch (roomChance)
		{
			case 1:
				firstRoom = new Room( "room01", "room01" );
			case 2:
				firstRoom = new Room( "room02", "room02" ); 
			case 3:
				firstRoom = new Room( "room03", "room03" ); 
		} 
		firstRoom.x = 25;
		firstRoom.y = 0;
		addChild( firstRoom );
		rooms.push( firstRoom );
		rooms[0].placeExit();
		
		var l_exit:Item = rooms[ 0 ].items[ rooms[0].items.length - 1 ];
		targetPoint = new Point( l_exit.x, l_exit.y );
		
		// TODO: Something wrong here when items added.
		var roomQueue:Array<Room> = new Array<Room>();
		roomQueue.push(firstRoom);
		
		while (rooms.length < maxRoomCount)
		{
			var curRoom:Room  = roomQueue.shift();
			
			for (dir in 0...4)
			{
				// Fill each possible direction
				if (curRoom.doorSlots[dir] != -1 && curRoom.neighbors[dir]==null)
				{
					
					//Try all rooms to place here
					var possNewRooms = ["room01", "room02", "room03", "room04", "room05"];
					while (possNewRooms.length > 0) { //Generate an appropriate room.  WILL be "loop until all rooms tried in this slot"
						var nextRoomIndex = Std.random(possNewRooms.length);
						var nextRoomName = possNewRooms.splice(nextRoomIndex, 1)[0];
						
						var nextRoom:Room = new Room(nextRoomName, nextRoomName);
						
						if (nextRoom.doorSlots[(dir + 2) % 4] == -1)
						{
							continue; // no slots available on opposite side!
						}
					
						addChild(nextRoom);
						
						nextRoom.x = curRoom.x;
						nextRoom.y = curRoom.y;
						switch (dir) {
							case 2:
								nextRoom.y += curRoom.height+roomBuffer;
								nextRoom.x += curRoom.doorSlots[dir] - nextRoom.doorSlots[(dir + 2) % 4];
								
							case 0:
								nextRoom.y -= nextRoom.height+roomBuffer;
								nextRoom.x += curRoom.doorSlots[dir] - nextRoom.doorSlots[(dir + 2) % 4];
								
							case 1:
								nextRoom.x += curRoom.width+roomBuffer;
								nextRoom.y += curRoom.doorSlots[dir] - nextRoom.doorSlots[(dir + 2) % 4];
								
							case 3:
								nextRoom.y += curRoom.doorSlots[dir] - nextRoom.doorSlots[(dir + 2) % 4];
								nextRoom.x -= nextRoom.width+roomBuffer;
						}
						
						if (nextRoom.x < -levelDiameter/2 ||
							nextRoom.x + nextRoom.width > levelDiameter/2 ||
							nextRoom.y < -levelDiameter/2 ||
							nextRoom.y + nextRoom.height > levelDiameter/2)
						{

							#if debug
								trace(nextRoom);
							#end
							
							removeChild(nextRoom);
							continue;
						}
						
						//TODO: CONFIRM THAT DOORS DO NOT INSTERSECT WITH OTHER ROOMS
						
						
						//Door confirmed, add door
						curRoom.neighbors[dir] = nextRoom;
						nextRoom.neighbors[(dir + 2) % 4] = curRoom;
						rooms.push(nextRoom);
						
						var newDoor:Door = new Door();
						curRoom.doors.push(newDoor);
						nextRoom.doors.push(newDoor);
						// TODO: Add door and position
						//addChild(newDoor);
						//newDoor.x, newDoor.y
						
					
						roomQueue.push(nextRoom);
						break;
					}
				}
				
			//Room's neighbors are decided, find wall occlusions
			if (rooms.length == maxRoomCount || roomQueue.length == 0) break;
				
			}
		}
		
		//occlude rooms and construct walls
		for (room in rooms) 
		{
			room.occlude();
			room.setWalls();
		}
	}
	
	public function makeItems():Void {
	
	}
	
	/*public function makeExit():Void {
		targetPoint = new Point( HBH.STAGE_WIDTH / 2, HBH.STAGE_HEIGHT / 2 );
	}*/
	
	public function update( l_deltaTime:Int ) {
		var l_prevX:Float = x;
		var l_prevY:Float = y;
		
		if ( InputManager.isKeyDown( InputManager.W_KEY ) || InputManager.isKeyDown( InputManager.S_KEY ) )
		{
			if ( InputManager.isKeyDown( InputManager.W_KEY ) )
			{
				y += Player.SPEED;
				if (LevelScreen.player.getAnimation() != "move_up")
				{
					LevelScreen.player.setAnimation("move_up");
				}
			}
			if ( InputManager.isKeyDown( InputManager.S_KEY ) )
			{
				y -= Player.SPEED;
				if (LevelScreen.player.getAnimation() != "move_down")
				{
					LevelScreen.player.setAnimation("move_down");
				}
			}
			if (LevelScreen.player.currentSprite.currentBehavior.name.indexOf("move") != -1)
			{
				if (LevelScreen.player.currentSprite.currentFrameIndex == 1)
				{
					SoundPlayer.playFootsteps1();
				}
				else if (LevelScreen.player.currentSprite.currentFrameIndex == 3)
				{
					SoundPlayer.playFootsteps2();
				}
			}
			
		}
		else if ( InputManager.isKeyDown( InputManager.A_KEY ) || InputManager.isKeyDown( InputManager.D_KEY ) )
		{
			if ( InputManager.isKeyDown( InputManager.A_KEY ) )
			{
				x += Player.SPEED;
				if (LevelScreen.player.getAnimation() != "move_left")
				{
					LevelScreen.player.setAnimation("move_left");
				}
			}
			if ( InputManager.isKeyDown( InputManager.D_KEY ) )
			{
				x -= Player.SPEED;
				if (LevelScreen.player.getAnimation() != "move_right")
				{
					LevelScreen.player.setAnimation("move_right");
				}
			}
			if (LevelScreen.player.currentSprite.currentBehavior.name.indexOf("move") != -1)
			{
				if (LevelScreen.player.currentSprite.currentFrameIndex == 1)
				{
					SoundPlayer.playFootsteps1();
				}
				else if (LevelScreen.player.currentSprite.currentFrameIndex == 3)
				{
					SoundPlayer.playFootsteps2();
				}
			}
		}
		else if ( !InputManager.isKeyDown( InputManager.A_KEY ) && !InputManager.isKeyDown( InputManager.D_KEY ) && !InputManager.isKeyDown( InputManager.W_KEY ) && !InputManager.isKeyDown( InputManager.S_KEY ) )
		{
			LevelScreen.player.stopMovement();
			SoundPlayer.stopFootsteps();
		}
		
		
		
		var l_walls:Array<Dynamic>;
		for ( l_room in rooms )
		{
			//Tools.trace("room");
			l_walls = l_room.walls;
			//Tools.trace(l_walls);
			for ( l_wall in l_walls )
			{
				//Tools.trace("wall");
				if ( CollisionDetection.isPixelPerfectColliding( LevelScreen.player.hitBox, l_wall, this, true, 0 ) )
				{
					//Tools.trace("collides");
					LevelScreen.handleWallCollision( l_room, l_wall, l_prevX, l_prevY );
				}
			}
			
			l_room.update( l_deltaTime );
		}
		
		if ( ( Math.abs( x - l_prevX ) <= 0 ) && ( ( Math.abs( y - l_prevY ) <= 0 ) ) )
		{
			LevelScreen.player.stopMovement();
			SoundPlayer.stopFootsteps();
		}
		
	}

}
